package com.smx.steppingstone.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

public class ReflectUtil {
	public static Object getMethodValue(Object value, Method method) throws Exception {
		Object propertyValue = null;				
		try {
			propertyValue = method.invoke(value, new Object[0]);
		} catch (Exception e) {
			throw new Exception("Cannot get field " + method.getDeclaringClass().getName() + "."
					+ method.getName());
		}		
		return propertyValue;
	}

	/**
	 * Only process is/get methods without any parameters		
	 * @param o
	 * @return
	 */
	public static List<Method> getGetterOrIsMethods(Object o){
		List<Method> items=new ArrayList<Method>();
		for(Class<?> superClazz=o.getClass();superClazz!=Object.class; superClazz=superClazz.getSuperclass()){
			for(Method method : superClazz.getDeclaredMethods()){	
				if(method.isSynthetic() || 
						Modifier.isPrivate(method.getModifiers()) ||					
						method.getParameterTypes().length!=0 ||
						method.getReturnType().getName().equals("void")	||
						Modifier.isStatic(method.getModifiers()) ||
						Modifier.isProtected(method.getModifiers())		
				)continue;

				/*
				 FIXME:need to be able reliably inspect a method
				if(Modifier.isProtected(method.getModifiers())){
					method.setAccessible( true );

					continue;
				}
				 */
				items.add(method);
			}
		}
		return items;
	}

	/**
	 * Find all fields that can be inspected	
	 * @param o
	 * @return
	 */
	public static List<Field> getAccesibleFields(Object o){
		List<Field> items=new ArrayList<Field>();
		for(Class<?> superClazz=o.getClass(); superClazz!=Object.class; superClazz=superClazz.getSuperclass()){		
			for(Field field : superClazz.getDeclaredFields()){
				System.out.println(field);
				//Prevent illegal access exception
				if (field.isSynthetic() || Modifier.isPrivate(field.getModifiers())
						|| Modifier.isFinal(field.getModifiers()) 
						|| Modifier.isStatic(field.getModifiers())

				)continue;
				if(Modifier.isProtected(field.getModifiers())){
					//continue;
				//	field.setAccessible(true);
				}
				items.add(field);			
			}
		}
		return items;
	}
}
